package com.vinfai.common.dao;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.hibernate.type.Type;

import com.vinfai.common.exception.DataAccessException;
import com.vinfai.utils.orm.Page;
/**
 * 
 * 定义DAO接口,有些方法子类不实现直接抛出异常
 * @author vinfai
 *
 * @param <E> 实体对象类型
 * @param <PK> 主键类型
 */
public interface IEntityDAO <E,PK extends Serializable>{
	
	public PK save(E entity) throws DataAccessException;
	
	public void saveOrUpdate(E entity) throws DataAccessException;
	
	public void update(E entity) throws DataAccessException;
	
	public void merge(E entity) throws DataAccessException;
	
	public void deleteById(PK id) throws DataAccessException;
	
	public void delete(E entity) throws DataAccessException;
	
	public E getById(PK id) throws DataAccessException;

	/**
	 * 批量更新
	 * @param updateSql hibernate bluk update/delete sql String.
	 * @param params 参数Map集合
	 * @return	numbers of PO affected by update operation
	 * @throws DataAccessException
	 */
	public int bulkUpdate(String updateSql,Map<String,?> params) throws DataAccessException;
	
	public int bulkUpdate(String updateSql) throws DataAccessException;
	/**
	 * 更新或者删除操作，数组参数的次序需要同SQL中位置保持一致
	 * @param updateSql hibernate bluk update/delete sql String.
	 * @param params   参数数组
	 * @return numbers 更新的记录数
	 * @throws DataAccessException
	 */
	public int bulkUpdate(String updateSql,Object... params)throws DataAccessException;
	
	public int bulkNativeUpdate(String nativeSql)throws DataAccessException;
	/**
	 * 通过原始SQL更新操作，参数同bulkUpdate
	 * @param nativeSql
	 * @param params Map 参数通过name匹配
	 * @return
	 * @throws DataAccessException
	 */
	public int bulkNativeUpdate(String nativeSql,Map<String,?> params)throws DataAccessException;
	
	public int bulkNativeUpdate(String nativeSql,Object... params)throws DataAccessException;
	
	
	public <T> List<T> find(String hql,Map<String,?> params) throws DataAccessException;
	public <T> List<T> find(String hql,Object... params) throws DataAccessException;
	
	public <T> List<T> find(String hql,int firstResult,int maxResults,Map<String,?> params)throws DataAccessException;
	/**
	 * 
	 * @param <T> 返回值泛型
	 * @param hql 查询HQL语句
	 * @param firstResult 开始位置 first result
	 * @param maxResults max result
	 * @param params 
	 * @return 泛型集合
	 * @throws DataAccessException
	 */
	public <T> List<T> find(String hql,int firstResult,int maxResults,Object...params)throws DataAccessException;
	
	
	public <T> List<T> findNativeQuery(final String nativeSql,final int firstResult,final int maxResults,final Object... params) throws DataAccessException;

	public <T> List<T> findNativeQuery(final String nativeSql,final int firstResult,final int maxResults,final Map<String,?> params) throws DataAccessException;
	/**
	 * 查询结果集每一行封装成MAP形式
	 * @param <T>
	 * @param nativeSql
	 * @param firstResult
	 * @param maxResults
	 * @param params
	 * @return
	 * @throws DataAccessException
	 */
	public <T> List<T> findNativeQueryToMap(final String nativeSql,final int firstResult,final int maxResults,final Map<String,Type> scalarMap,final Object... params) throws DataAccessException;
	
	public <T> List<T> findNativeQueryToBean(final String nativeSql,final int firstResult,final int maxResults,final Class<T> beanClass,final Map<String,Type> scalarMap,final Object... params) throws DataAccessException;
	
	/**
	 * 按HQL查询唯一对象.，如分页是数据总数-->返回的类型为Long
	 * 
	 * @param values 数量可变的参数，按顺序绑定
	 */
	public <T> T findUnique(final String hql, final Object... params)throws DataAccessException;

	/**
	 * 按HQL查询唯一对象.
	 * 
	 * @param values 命名参数,按顺序绑定
	 */
	public <T> T findUnique(final String hql, final Map<String, ?> params)throws DataAccessException;
	/**
	 * 通过原始SQL查询唯一，如分页是数据总数-->返回的类型为BigInteger
	 * @param <T>
	 * @param nativeSql
	 * @param params
	 * @return
	 * @throws DataAccessException
	 */
	public <T> T findUniqueByNativeSQL(final String nativeSql,final Object... params)throws DataAccessException;
	/**
	 * 通过原始SQL查询唯一，如分页是数据总数.
	 * @param <T>
	 * @param nativeSql
	 * @param params
	 * @return
	 * @throws DataAccessException
	 */
	public <T> T findUniqueByNativeSQL(final String nativeSql,final Map<String,?> params) throws DataAccessException;
	
	public <T> T countSQLResult(final String nativeSql,final Map<String,?> params,final Map<String,Type> scalarMap);
}
